package com.yuerlive.rainbow.module.game;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.graphics.Bitmap;
import android.os.Handler;
import android.os.Message;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AnimationUtils;
import android.view.animation.ScaleAnimation;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;

import com.google.protobuf.InvalidProtocolBufferException;
import com.mrd.game.message.HOpCodeEx;
import com.mrd.game.message.RainbowMessage;
import com.mrd.mina.MinaCallback;
import com.mrd.mina.MinaHelper;
import com.mrd.packet.Packet;
import com.yuerlive.rainbow.R;
import com.yuerlive.rainbow.common.AppConfig;
import com.yuerlive.rainbow.entity.BaseData;
import com.yuerlive.rainbow.entity.GameInfo;
import com.yuerlive.rainbow.entity.Gift;
import com.yuerlive.rainbow.entity.LiveDetailData;
import com.yuerlive.rainbow.entity.NiuniuHistory;
import com.yuerlive.rainbow.entity.Poker;
import com.yuerlive.rainbow.entity.User;
import com.yuerlive.rainbow.entity.UserInfo;
import com.yuerlive.rainbow.module.game.adapter.NiuNiuHistoryAdapter;
import com.yuerlive.rainbow.module.game.adapter.WinerGiftAdapter;
import com.yuerlive.rainbow.module.game.presenter.GamePresenter;
import com.yuerlive.rainbow.module.game.presenter.GameContract;
import com.yuerlive.rainbow.module.live.LiveRoomActivity;
import com.yuerlive.rainbow.module.live.fragment.FragmentLayer;
import com.yuerlive.rainbow.module.playlive.PlayLiveRoomActivity;
import com.yuerlive.rainbow.module.recharge.RechargeActivity;
import com.yuerlive.rainbow.observer.Observerable;
import com.yuerlive.rainbow.observer.ObserverableType;
import com.yuerlive.rainbow.utils.DeviceUtils;
import com.yuerlive.rainbow.utils.L;
import com.yuerlive.rainbow.utils.UserProxy;
import com.yuerlive.rainbow.widget.CustomDialog;
import com.yuerlive.rainbow.widget.HorizontalListView;
import com.yuerlive.rainbow.widget.game.NiuniuLayout;
import com.yuerlive.rainbow.widget.game.PokerView;

import org.apache.mina.core.session.IoSession;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import butterknife.BindBitmap;
import butterknife.BindColor;
import butterknife.BindView;
import butterknife.OnClick;

/**
 * Created by xiaoyi on 2017/5/27.
 * 牛牛游戏
 */

public class FragmentGameNiuniu extends FragmentGameBase<GameContract.Presenter> implements MinaCallback, GameContract.View, UserProxy.OnUserChangeListener {

    final static int CODE_FAPAI = 0X1001;  //发牌
    final static int CODE_KAIPAI = 0X1002; //开牌
    final static int CODE_RELAX = 0X1003; //休息一会
    final static int CODE_CALCULATE = 0X1004; //结算

    final static int CODE_DEAL = 0X2001;  //下注
    final static int CODE_UPDATE_DEAL = 0X2002;  //更新下注情况
    final static int CODE_DEAL_RESULT = 0X2003;  //下注结果

    final static int CODE_DEAL_COUNTDOWN = 0X3001; //下注倒计时
    final static int CODE_CALCULATE_COUNTDOWN = 0X3002;//结算倒计时

    final static int CODE_CHANGE_GAME = 0X4001; //切换游戏

    final static int CODE_CLOSE_GAME = 0X4002; //关闭游戏

    final static int GAME_ID = 1;

    @BindColor(R.color.white_50)
    int colorUnEnable;
    @BindColor(R.color.white)
    int colorWhite;


    @BindBitmap(R.drawable.gold_icon)
    Bitmap gold;
    @BindBitmap(R.drawable.gold_icon_gray)
    Bitmap goldGray;

    private int chessboardId;
    private int liveID;

    private GameInfo gameInfo;
    @BindView(R.id.left)
    NiuniuLayout left;
    @BindView(R.id.center)
    NiuniuLayout center;
    @BindView(R.id.right)
    NiuniuLayout right;
    @BindView(R.id.tvCount)
    TextView tvCount;

    @BindView(R.id.tvchips10)
    TextView tvchips10;

    @BindView(R.id.tvchips100)
    TextView tvchips100;

    @BindView(R.id.tvchips1000)
    TextView tvchips1000;

    @BindView(R.id.pokerStart1)
    FrameLayout pokerStart1;
    @BindView(R.id.pokerStart2)
    FrameLayout pokerStart2;
    @BindView(R.id.pokerStart3)
    FrameLayout pokerStart3;

    @BindView(R.id.tvState)
    TextView tvState;
    @BindView(R.id.tvTimer)
    TextView tvTimer;

    @BindView(R.id.llchips10)
    LinearLayout llchips10;
    @BindView(R.id.llchips100)
    LinearLayout llchips100;
    @BindView(R.id.llchips1000)
    LinearLayout llchips1000;
    @BindView(R.id.llchips10000)
    LinearLayout llchips10000;
    @BindView(R.id.tvchips10000)
    TextView tvchips10000;
    ScaleAnimation stateShowAnim;
    ScaleAnimation stateHideAnim;

    private boolean canDeal;
    private RainbowMessage.GCResultRet niuniuResult;

    private User user;

    private boolean isDialogShowing;

    @Override
    protected int getLayoutId() {
        return R.layout.fragment_game_niuniu;
    }

    int count = 0;

    int chipsSelected = 10;
    int myDealLeft = 0;
    int myDealCenter = 0;
    int myDealRight = 0;

    private float gameTimes = 2.8f;

    Thread minaThread;

    private GameHandler mHandler;


    private CustomDialog hisResult;  //历史输赢
    private CustomDialog winDialog;  //获胜奖励

    private ListView lvHistory;
    private NiuNiuHistoryAdapter hisAdapter;
    private List<NiuniuHistory> mHisDatas = new ArrayList<>();
    private TextView tvWins;
    private int dealCountDown = 30;
    private int VAULE_DEALCOUNTDOWN = 30;
    private LiveDetailData liveDetail;

    private long requestGameStateTime;

    public FragmentGameNiuniu() {
        presenter = new GamePresenter(this);
        user = UserProxy.getUser();
    }

    @Override
    public void initViews(View root) {
        if (mActivity instanceof PlayLiveRoomActivity) {
            liveID = Integer.parseInt(user.getUserInfo().getLiveId());
            ((PlayLiveRoomActivity) mActivity).setGameID(GAME_ID);
        }
        mHandler = new GameHandler(this);
        ((GamePresenter)presenter).getGameInfo(""+GAME_ID);
        stateShowAnim = (ScaleAnimation) AnimationUtils.loadAnimation(mActivity, R.anim.state_show);
        minaThread = new Thread(() -> {
            MinaHelper.getInstance().connect(this, false);
        });
        minaThread.start();
        initHisResultDialog();
        initWinDialog();
        initData();
        UserProxy.addListener(this);
        L.e(TAG, "initviews    niuniu");
    }

    private void initData() {
        tvCount.setText(user.getUserInfo().getRainbowSweet() + "");
        checkChipsSelect(llchips10000, 10000);
        checkChipsSelect(llchips1000, 1000);
        checkChipsSelect(llchips100, 100);
    }

    /*初始化历史记录对话框*/
    private void initHisResultDialog() {
        if (hisResult == null) {
            View view = LayoutInflater.from(mActivity).inflate(R.layout.layout_history_result, null);
            hisResult = new CustomDialog(mActivity, view);
            lvHistory = (ListView) view.findViewById(R.id.lvHistory);
            view.findViewById(R.id.ivCancel).setOnClickListener(
                    (v) -> hisResult.hide()
            );
            hisAdapter = new NiuNiuHistoryAdapter(mActivity, mHisDatas);
            lvHistory.setAdapter(hisAdapter);
            hisResult.hide();
        }
    }

    /*初始化获胜对话框*/
    private void initWinDialog() {
        if (winDialog == null) {
            View view = LayoutInflater.from(mActivity).inflate(R.layout.layout_dialog_win, null);
            winDialog = new CustomDialog(mActivity, view);
            view.findViewById(R.id.ivCancel).setOnClickListener(
                    (v) -> winDialog.hide()
            );
            tvWins = (TextView) view.findViewById(R.id.tvWins);
            winDialog.hide();
        }
    }


    private int calculateResult(int index) {
        canDeal = false;
        int result = 0;
        switch (index) {
            case 1:
                result = (int) (myDealLeft * gameTimes /*- myDealLeft - myDealCenter - myDealRight*/);
                break;
            case 2:
                result = (int) (myDealCenter * gameTimes /*- myDealCenter - myDealLeft - myDealRight*/);
                break;
            case 3:
                result = (int) (myDealRight * gameTimes /*- myDealRight - myDealCenter - myDealLeft*/);
                break;
        }
        int rainBowSweet = user.getUserInfo().getRainbowSweet();
        rainBowSweet += (result/* + myDealLeft + myDealRight + myDealCenter*/);
        user.getUserInfo().setRainbowSweet(rainBowSweet);
        UserProxy.setUser(user);
        if (result > 0 && (myDealLeft + myDealCenter + myDealRight) > 0) {
            showWins(result);
        } else if ((myDealLeft + myDealCenter + myDealRight) > 0) {

            showState("竞猜失败，再接再厉").postDelayed(
                    () -> {
                        if (tvState == null) return;
                        tvState.setVisibility(View.GONE);
                    }, 3000
            );
            tvState.postDelayed(() -> takeABreak(), 3000);
        } else {
            tvState.postDelayed(() -> takeABreak(), 3000);
        }
        return Math.max(0, result);
    }

    private void showWins(int count) {
        tvWins.setText("x" + count);
        List<Gift> gifts = new ArrayList<>();
        HorizontalListView lvGift = (HorizontalListView) winDialog.findViewById(R.id.lvGift);
        LinearLayout llGift = (LinearLayout) winDialog.findViewById(R.id.llGift);
        if (mActivity instanceof LiveRoomActivity) {
            gifts.clear();
            for (int i = 0; i < winGifts.length; i++) {
                Gift gift = findGiftById(liveDetail.getGiftList(), winGifts[i]);
                if (gift != null) {
                    if (i == 0) gift.setChoosed(1);
                    else gift.setChoosed(0);
                    gifts.add(gift);
                }
            }

            WinerGiftAdapter adapter = new WinerGiftAdapter(mActivity, gifts);
            llGift.setVisibility(View.VISIBLE);
            lvGift.setAdapter(adapter);
            lvGift.setOnItemClickListener((parent, v, pos, id) -> {
                for (Gift gift : gifts) {
                    gift.setChoosed(0);
                }
                gifts.get(pos).setChoosed(1);
                adapter.notifyDataSetChanged();
            });
            TextView tvSend = (TextView) winDialog.findViewById(R.id.tvSend);
            tvSend.setOnClickListener((v) -> {
                for (Gift gift : gifts) {
                    if (gift.getChoosed() == 1) {
                        if (user.getUserInfo().getRainbowSweet()<gift.getGiftRainbowSweet()){
                            showToast("彩虹豆不足");
                        }else {
                            ((FragmentLayer) getParentFragment()).sendGift(gift);
                            winDialog.hide();
                            return;
                        }
                    }
                }
            });
        } else {
            llGift.setVisibility(View.GONE);
        }
        winDialog.show();
        tvWins.postDelayed(
                () -> winDialog.hide(), 3000
        );
        tvWins.postDelayed(() -> takeABreak(), 3000);
    }

    public void setLiveDetail(LiveDetailData liveDetailData) {
        if (liveDetailData == null) return;
        this.liveDetail = liveDetailData;
        liveID = Integer.parseInt(liveDetail.getInfo().getLiveId());
    }

    @Override
    public void setPresenter(GameContract.Presenter presenter) {
        this.presenter = presenter;
    }

    @Override
    public void showLoading() {

    }

    @Override
    public void hideLoading() {

    }

    @Override
    public void onUserChange(User user) {
        this.user = user;
        initData();
    }

    private void checkChipsSelect(LinearLayout linearLayout, int select) {
        int sweetNum = user.getUserInfo().getRainbowSweet();
        switch (select) {
            case 10000:
                if (sweetNum < 10000 && sweetNum >= 1000 && chipsSelected == 10000) {
                    chipsSelected = 1000;
                    changeChips(1000);
                }
                break;
            case 1000:
                if (sweetNum < 1000 && sweetNum >= 100 && chipsSelected == 1000) {
                    chipsSelected = 100;
                    changeChips(100);
                }
                break;
            case 100:
                if (sweetNum < 100 && chipsSelected == 100) {
                    chipsSelected = 10;
                    changeChips(10);
                }
                break;
        }
        if (sweetNum < select) {
            ((ImageView) linearLayout.getChildAt(0)).setImageBitmap(goldGray);
            ((TextView) linearLayout.getChildAt(1)).setTextColor(colorUnEnable);
            linearLayout.setEnabled(false);
        } else {
            ((ImageView) linearLayout.getChildAt(0)).setImageBitmap(gold);
            ((TextView) linearLayout.getChildAt(1)).setTextColor(colorWhite);
            linearLayout.setEnabled(true);
        }
    }

    public boolean isDialogShowing() {
        boolean isShowing = winDialog != null && winDialog.isShowing();
        if (isShowing) return isShowing;
        isShowing = hisResult != null && hisResult.isShowing();
        return isShowing;
    }


    /**
     * 游戏逻辑处理
     */
    private static class GameHandler extends Handler {
        WeakReference<FragmentGameNiuniu> weakReference;
        FragmentGameNiuniu fragment;

        public GameHandler(FragmentGameNiuniu context) {
            this.weakReference = new WeakReference<FragmentGameNiuniu>(context);
            this.fragment = weakReference.get();
        }

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case CODE_FAPAI: //发牌
                    fragment.doFapai();
                    break;
                case CODE_KAIPAI:  //开牌
                    fragment.kaipai((RainbowMessage.GCResultRet) msg.obj);
                    break;
                case CODE_DEAL:
                    removeMessages(CODE_CALCULATE_COUNTDOWN);
                    fragment.doActionDeal();
                    break;
                case CODE_DEAL_COUNTDOWN:
                    if (fragment.dealCountDown > 0) {
                        fragment.canDeal = true;
                        fragment.tvTimer.setVisibility(View.VISIBLE);
                        fragment.showCountDown(fragment.dealCountDown);
                        fragment.dealCountDown--;
                        sendEmptyMessageDelayed(CODE_DEAL_COUNTDOWN, 1000);
                        if (fragment.dealCountDown <= 5 && fragment.niuniuResult == null) {
                            // fragment.sendResultReq();
                        }

                    } else {
                        fragment.tvTimer.setText("0");
                        fragment.dealCountDown = fragment.VAULE_DEALCOUNTDOWN;
//                        fragment.canDeal = false;
                        /*if (fragment.niuniuResult != null) {
                            msg = obtainMessage();
                            msg.what = CODE_KAIPAI;
                            msg.obj = fragment.niuniuResult;
                            sendMessage(msg);
                        } else {
                            fragment.showToast("服务器返回牌局失败");
                        }*/
                    }
                    break;
                case CODE_RELAX:
                    fragment.takeABreak();
                    break;
                case CODE_CALCULATE: //结算

                    fragment.doCalculateResult(msg.arg1);
                    break;
                case CODE_CALCULATE_COUNTDOWN://结算显示倒计时
                    int countdown = msg.arg1;
                    fragment.tvTimer.setVisibility(View.GONE);
                    removeMessages(CODE_DEAL_COUNTDOWN);
                    if (countdown > 0) {
                        fragment.tvTimer.setText("" + countdown);
                        countdown--;
                        msg = obtainMessage();
                        msg.arg1 = countdown;
                        msg.what = CODE_CALCULATE_COUNTDOWN;
                        sendMessageDelayed(msg, 1000);
                    } else {
                        fragment.tvTimer.setText("0");
                    }
                    break;
                case CODE_UPDATE_DEAL:
                    fragment.updateDealInfo((RainbowMessage.GCCathNowInfoRet) msg.obj);
                    break;
                case CODE_DEAL_RESULT:
                    try {
                        fragment.setDealView((RainbowMessage.GCBetRet) msg.obj);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    break;
                case CODE_CHANGE_GAME:
                    fragment.changeGame((Integer) msg.obj);
                    break;
            }
        }
    }

    @OnClick({
            R.id.llchips10, R.id.llchips100, R.id.llchips1000,R.id.llchips10000, R.id.ivHistory, R.id.tv_recharge,
            R.id.left, R.id.center, R.id.right,
    })
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.llchips10:
                changeChips(10);
                break;
            case R.id.llchips100:
                changeChips(100);
                break;
            case R.id.llchips1000:
                changeChips(1000);
                break;
            case R.id.llchips10000:
                changeChips(10000);
                break;
            case R.id.ivHistory:
                ((GameContract.Presenter) presenter).getGameHistory("" + liveID, "" + GAME_ID);
                break;
            case R.id.tv_recharge:
                jumpToActivity(RechargeActivity.class);
                break;
            case R.id.left:
                if (canDeal) {
                    if (checkSweet()) {
                        sendDealMsg(1);
                    } else {
                        showToast("彩虹糖不足，请充值");
                    }
                }
                break;
            case R.id.right:
                if (canDeal) {
                    if (checkSweet()) {
                        sendDealMsg(3);
                    } else {
                        showToast("彩虹糖不足，请充值");
                    }
                }
                break;
            case R.id.center:
                if (canDeal) {
                    if (checkSweet()) {
                        sendDealMsg(2);
                    } else {
                        showToast("彩虹糖不足，请充值");
                    }
                }
                break;
        }
    }

    private boolean checkSweet() {
        return user.getUserInfo().getRainbowSweet() >= chipsSelected;
    }

    private boolean doDeal(NiuniuLayout view, int num, int total, int index) {
        UserInfo info = user.getUserInfo();
        if (info.getRainbowSweet() >= num) {
            total += num;
            view.doDeal(total);
            switch (index) {
                case 1:
                    myDealLeft = total;
                    break;
                case 2:
                    myDealCenter = total;
                    break;
                case 3:
                    myDealRight = total;
                    break;
            }
            info.setRainbowSweet(info.getRainbowSweet() - num);
            user.setUserInfo(info);
            UserProxy.setUser(user);
            Observerable.getInstance().notifyChange(ObserverableType.HASDEAL,true);
            return true;
        } else {
            showToast("彩虹糖不足，请充值");
            return false;
        }
    }

    @Override
    public void showHistoryResult(BaseData<List<NiuniuHistory>> results) {
        mHisDatas.clear();
        mHisDatas.addAll(results.getObject());
        hisAdapter.notifyDataSetChanged();
        lvHistory.measure(0, 0);
        ViewGroup.LayoutParams layoutParams = lvHistory.getLayoutParams();
        if (mHisDatas.size() >= 6) {
            layoutParams.height = DeviceUtils.dp2px(mActivity, 245);
            lvHistory.setLayoutParams(layoutParams);
        }
        hisResult.show();
    }

    @Override
    public void setGameInfo(GameInfo gameInfo) {
        this.gameInfo = gameInfo;
        initGame();
    }

    private void changeChips(int value) {
        chipsSelected = value;
        switch (value) {
            case 10:
                tvchips10.setBackgroundResource(R.drawable.bg_niuniu_chips_selected);
                tvchips100.setBackgroundResource(R.drawable.bg_niuniu_chips_unselected);
                tvchips1000.setBackgroundResource(R.drawable.bg_niuniu_chips_unselected);
                tvchips10000.setBackgroundResource(R.drawable.bg_niuniu_chips_unselected);
                break;
            case 100:
                tvchips100.setBackgroundResource(R.drawable.bg_niuniu_chips_selected);
                tvchips10.setBackgroundResource(R.drawable.bg_niuniu_chips_unselected);
                tvchips1000.setBackgroundResource(R.drawable.bg_niuniu_chips_unselected);
                tvchips10000.setBackgroundResource(R.drawable.bg_niuniu_chips_unselected);
                break;
            case 1000:
                tvchips1000.setBackgroundResource(R.drawable.bg_niuniu_chips_selected);
                tvchips100.setBackgroundResource(R.drawable.bg_niuniu_chips_unselected);
                tvchips10.setBackgroundResource(R.drawable.bg_niuniu_chips_unselected);
                tvchips10000.setBackgroundResource(R.drawable.bg_niuniu_chips_unselected);
                break;
            case 10000:
                tvchips10000.setBackgroundResource(R.drawable.bg_niuniu_chips_selected);
                tvchips100.setBackgroundResource(R.drawable.bg_niuniu_chips_unselected);
                tvchips10.setBackgroundResource(R.drawable.bg_niuniu_chips_unselected);
                tvchips1000.setBackgroundResource(R.drawable.bg_niuniu_chips_unselected);
                break;
        }
    }

    /*执行发牌动画*/
    private void doFapai() {
        canDeal = false;
        if (tvState == null) return;
        tvState.setVisibility(View.GONE);
        tvTimer.setVisibility(View.GONE);
        AnimatorSet set = new AnimatorSet();
        Animator leftAnim = playDealAnim(left, pokerStart1);
        Animator centerAnim = playDealAnim(center, pokerStart2);
        centerAnim.setStartDelay(600);
        Animator rightAnim = playDealAnim(right, pokerStart3);
        rightAnim.setStartDelay(1200);
        set.playTogether(leftAnim, centerAnim, rightAnim);
        set.start();
        set.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);
                if (tvState != null) {
                    tvState.postDelayed(() -> {
                        showState("开始下注");
                        if (GAMESTATE != 2)
                            tvState.postDelayed(() -> {
                                if (tvState == null) return;
                                tvState.setVisibility(View.GONE);
                            }, 1000);
                    }, 1000);
                }
            }
        });
    }

    /*开牌动画*/
    private void kaipai(RainbowMessage.GCResultRet resultRet) {
        canDeal = false;
        if (GAMESTATE == 5) return;
        GAMESTATE = 5;
        int animTime = 2000;
        if (System.currentTimeMillis() - requestGameStateTime < 500) {
            animTime = 0;
        }
        if (tvTimer == null) return;
        tvTimer.setVisibility(View.GONE);
        tvState.setVisibility(View.GONE);
        if (resultRet == null) return;
        left.showBack();
        center.showBack();
        right.showBack();
        List<Poker> leftpokers = new ArrayList<>();
        for (int i = 0; i < 5; i++) {
            RainbowMessage.Card card = resultRet.getCardsSet1().getCards(i);
            Poker poker = new Poker(card.getCardNoShow(),
                    PokerView.PokerType.valueOf(card.getCardColor()));
            leftpokers.add(poker);
        }
        if (left == null) {
            return;
        }
        left.setPokers(leftpokers);
        left.setResult(resultRet.getCardsSet1().getNameNo());
        tvState.postDelayed(() -> {
            List<Poker> centerpokers = new ArrayList<>();
            for (int i = 0; i < 5; i++) {
                RainbowMessage.Card card = resultRet.getCardsSet2().getCards(i);
                Poker poker = new Poker(card.getCardNoShow(),
                        PokerView.PokerType.valueOf(card.getCardColor()));
                centerpokers.add(poker);
            }
            if (center == null) {
                return;
            }
            center.setPokers(centerpokers);
            center.setResult(resultRet.getCardsSet2().getNameNo());
        }, animTime);
        int finalAnimTime = animTime;
        tvState.postDelayed(() -> {
            List<Poker> rightpokers = new ArrayList<>();
            for (int i = 0; i < 5; i++) {
                RainbowMessage.Card card = resultRet.getCardsSet3().getCards(i);
                Poker poker = new Poker(card.getCardNoShow(),
                        PokerView.PokerType.valueOf(card.getCardColor()));
                rightpokers.add(poker);
            }
            if (right == null) {
                return;
            }
            right.setPokers(rightpokers);
            showWinner(resultRet.getWinIndex());
            right.setResult(resultRet.getCardsSet3().getNameNo());
            tvState.postDelayed(() -> {
                if (tvState == null) return;
                calculateResult(resultRet.getWinIndex());
            }, finalAnimTime);
        }, animTime * 2);
    }

    /*休息一会*/
    private void takeABreak() {
        if (switchGameID < 0) {
            cleanData();
            if (tvState == null) return;
            left.hide();
            right.hide();
            center.hide();
            showState("即将开始，请稍后");
        } else if (switchGameID == 0) {
            ((FragmentLayer) getParentFragment()).deleteGame();
        }

    }

    /*显示赢家*/
    private void showWinner(int index) {
        left.showCover(index != 1);
        center.showCover(index != 2);
        right.showCover(index != 3);
    }

    /*发牌动画*/
    private Animator playDealAnim(NiuniuLayout parent, ViewGroup pokerStart) {
        AnimatorSet animatorSet = new AnimatorSet();
        List<Animator> animators = new ArrayList<>();
        int[] location = new int[2];
        pokerStart.getChildAt(0).getLocationOnScreen(location);
        for (int i = 0; i < pokerStart.getChildCount(); i++) {
            PropertyValuesHolder tx = PropertyValuesHolder.ofFloat("translationX", 0,
                    parent.pokerLocations.get(i)[0] - location[0]);
            PropertyValuesHolder ty = PropertyValuesHolder.ofFloat("translationY", 0,
                    parent.pokerLocations.get(i)[1] - location[1]);
            PropertyValuesHolder rotation = PropertyValuesHolder.ofFloat("rotation", 0,
                    720);
            ObjectAnimator animator = ObjectAnimator.ofPropertyValuesHolder(pokerStart.getChildAt(i), tx, ty, rotation);
            animator.setDuration(1000);
            animator.setStartDelay(50 * i);
            animators.add(animator);

        }

        animatorSet.playTogether(animators);
        animatorSet.addListener(new AnimatorListenerAdapter() {
            @Override
            public void onAnimationEnd(Animator animation) {
                super.onAnimationEnd(animation);

                for (int i = 0; i < pokerStart.getChildCount(); i++) {
                    pokerStart.getChildAt(i).setTranslationX(0);
                    pokerStart.getChildAt(i).setTranslationY(0);
                    pokerStart.getChildAt(i).setVisibility(View.INVISIBLE);
                    parent.showBack();
                }
            }

            @Override
            public void onAnimationStart(Animator animation) {
                super.onAnimationStart(animation);
                for (int i = 0; i < pokerStart.getChildCount(); i++) {
                    pokerStart.getChildAt(i).setVisibility(View.VISIBLE);
                }
            }
        });
        return animatorSet;
    }

    /*状态提示view*/
    private TextView showState(String text) {
        if (tvState == null) return null;
        tvState.setText(text);
        if (tvState.getVisibility() != View.VISIBLE) {
            tvState.startAnimation(stateShowAnim);
        }
        tvState.setVisibility(View.VISIBLE);
        return tvState;
    }


    /*下注倒计时*/
    private TextView showCountDown(int countdown) {
        tvTimer.setText(String.valueOf(countdown));
        tvTimer.setVisibility(View.VISIBLE);
        return tvTimer;
    }


    @Override
    public void onDestroy() {
        hisResult.dismiss();
        winDialog.dismiss();
        MinaHelper.getInstance().removeCallback(this);
        mHandler.removeCallbacksAndMessages(null);
        UserProxy.removeListener(this);
        super.onDestroy();
        L.e(TAG, "ondestory    niuniu  " + AppConfig.isJumpFromLive);
    }

    /*游戏开始清空上一局数据*/
    private void cleanData() {
        if (left == null) return;
        left.clean();
        right.clean();
        center.clean();
        myDealCenter = 0;
        myDealRight = 0;
        myDealLeft = 0;
        Observerable.getInstance().notifyChange(ObserverableType.HASDEAL,false);
    }

    @Override
    public void onConnected(IoSession session) {
        L.e(TAG, "onConnected  ---------------");
        getGameState();
        if (mActivity instanceof LiveRoomActivity) {
            getDealInfo();
        }
    }

    @Override
    public void onException(IoSession session, Throwable cause) {

    }

    @Override
    public void onReceiveMessage(IoSession session, Object message) {
        Packet packet = (Packet) message;
        L.e(TAG, "GAMEState " + packet.getRetCode());
        Message msg;
        try {
            switch (packet.getPacketId()) {
                case HOpCodeEx.GCOpenRet:
                    RainbowMessage.GCOpenRet openResult = RainbowMessage.GCOpenRet.parseFrom((byte[]) packet.getData());
                    if (openResult.getCode() == 0) {//开局成功
                        chessboardId = openResult.getChessboardId();
                        msg = mHandler.obtainMessage();
                        msg.what = CODE_FAPAI;
                        msg.obj = openResult;
                        mHandler.sendMessage(msg);
                    } else {
                        showToast("服务器开局失败");
                        chessboardId = 0;
                    }

                    break;
                case HOpCodeEx.GCResultRet:
                    L.e(TAG, "游戏状态 5 开牌");
                    RainbowMessage.GCResultRet result = RainbowMessage.GCResultRet.parseFrom((byte[]) packet.getData());
                    if (result.getCode() == 0) {//返回成功
                        if (result.getGameId() != GAME_ID && result.getGameId() != 0) {
                            if (shouldNotChange){
//                                ((FragmentLayer)getParentFragment()).deleteGame();
                                MinaHelper.getInstance().removeCallback(this);
                            }else {
                                msg = mHandler.obtainMessage();
                                msg.obj = result.getGameId();
                                msg.what = CODE_CHANGE_GAME;
                                mHandler.sendMessage(msg);
                            }
                        } else {
                            niuniuResult = result;
                            msg = mHandler.obtainMessage();
                            msg.obj = niuniuResult;
                            msg.what = CODE_KAIPAI;
                            mHandler.sendMessage(msg);
                        }

                    } else {
                        showToast("服务器返回错误：code " + result.getCode());
                        chessboardId = 0;
                    }
                    break;
                case HOpCodeEx.GCGameStateRet:
                    doGameAction(packet);
                    break;
                case HOpCodeEx.GCCathNowInfoRet:
                    L.e(TAG, "下注 筹码池");
                    RainbowMessage.GCCathNowInfoRet dealInfo = RainbowMessage.GCCathNowInfoRet.parseFrom((byte[]) packet.getData());
                    msg = mHandler.obtainMessage();
                    msg.obj = dealInfo;
                    msg.what = CODE_UPDATE_DEAL;
                    mHandler.sendMessage(msg);
                    break;
                case HOpCodeEx.GCBetRet:
                    L.e(TAG, "time  return " + System.currentTimeMillis());
                    if (packet.getRetCode() == 0) {//下注成功
                        L.e(TAG, "下注成功返回");
                        RainbowMessage.GCBetRet gcBetRet = RainbowMessage.GCBetRet.parseFrom((byte[]) packet.getData());
                        msg = mHandler.obtainMessage();
                        msg.what = CODE_DEAL_RESULT;
                        msg.obj = gcBetRet;
                        mHandler.sendMessage(msg);
                    }
                    break;
                case HOpCodeEx.GCNowSweetInfoRet:
                    L.e(TAG, "rainbowsweet ");
                    RainbowMessage.GCNowSweetInfoRet gcNowSweetInfoRet = RainbowMessage.GCNowSweetInfoRet.parseFrom((byte[]) packet.getData());
                    UserInfo info = user.getUserInfo();
                    info.setFreezeSweet(gcNowSweetInfoRet.getFreezeSweet());
                    info.setAvailableSweet(gcNowSweetInfoRet.getFreezeSweet());
                    info.setRainbowSweet(gcNowSweetInfoRet.getTotalSweet());
                    user.setUserInfo(info);
                    UserProxy.setUser(user);
                    break;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void setDealView(RainbowMessage.GCBetRet betRet) throws Exception {
        if (left == null) return;
        int index = betRet.getIndex();
        switch (index) {
            case 1:
                doDeal(left, chipsSelected, myDealLeft, 1);
                break;
            case 2:
                doDeal(center, chipsSelected, myDealCenter, 2);
                break;
            case 3:
                doDeal(right, chipsSelected, myDealRight, 3);
                break;
        }
    }


    /*更新下注情况*/
    private void updateDealInfo(RainbowMessage.GCCathNowInfoRet dealInfo) {
        if (left == null) return;
        left.setDealTotal(dealInfo.getIndex1Total());
        //left.doDeal(dealInfo.getIndex1User());
        center.setDealTotal(dealInfo.getIndex2Total());
        //center.doDeal(dealInfo.getIndex2User());
        right.setDealTotal(dealInfo.getIndex3Total());
        //right.doDeal(dealInfo.getIndex3User());

        updateDealInfoAsFirst(dealInfo);
    }

    private void updateDealInfoAsFirst(RainbowMessage.GCCathNowInfoRet dealInfo) {
        if (mActivity instanceof LiveRoomActivity) {
            if (dealInfo.getIndex1User() > 0) {
                left.doDeal(dealInfo.getIndex1User());
                myDealLeft = dealInfo.getIndex1User();
            }
            if (dealInfo.getIndex2User() > 0) {
                center.doDeal(dealInfo.getIndex2User());
                myDealCenter = dealInfo.getIndex2User();
            }

            if (dealInfo.getIndex3User() > 0) {
                right.doDeal(dealInfo.getIndex3User());
                myDealRight = dealInfo.getIndex3User();
            }
            if (myDealLeft + myDealCenter + myDealRight > 0) {
                initData();
            }
        }
    }

    /*切换游戏*/
    private void changeGame(int gameID) {
        FragmentLayer layer = (FragmentLayer) getParentFragment();
        layer.switchGame(gameID);
        L.e(TAG,"CCCCCCCCCCCCCCCCCCCCC     444444444444");
    }

    /*游戏行为*/
    private void doGameAction(Packet packet) throws InvalidProtocolBufferException {
        RainbowMessage.GCGameStateRet gameStateRet = RainbowMessage.GCGameStateRet.parseFrom((byte[]) packet.getData());
        L.e(TAG, "GAMEState 游戏状态 " + gameStateRet.getState()
                + "  游戏局ID " + chessboardId
                + " 游戏id " + gameStateRet.getGameId()
                + "  倒计时 " + gameStateRet.getCountDown());
        if (gameStateRet.getGameId() != GAME_ID && gameStateRet.getGameId() != 0) {   //游戏id 和 当前游戏不一致，切游戏
            Message msg = mHandler.obtainMessage();
            msg.obj = gameStateRet.getGameId();
            msg.what = CODE_CHANGE_GAME;
            mHandler.sendMessage(msg);
        } else {
            if (GAMESTATE == gameStateRet.getState()) {
                return;
            }
            chessboardId = gameStateRet.getChessboardId();
            GAMESTATE = gameStateRet.getState();
            Message msg;
            switch (gameStateRet.getState()) {
                case 1:
                    L.e(TAG, "GAMEState 即将开始   " + new Date(System.currentTimeMillis()).toLocaleString());
                    if (switchGameID > 0) {  //切换游戏
                        ((FragmentLayer) getParentFragment()).switchGame(switchGameID);
                        L.e(TAG,"CCCCCCCCCCCCCCCCCCCCC     555555555555");
                    } else if (switchGameID == 0) {
                        ((FragmentLayer) getParentFragment()).deleteGame();
                    } else {
                        mHandler.sendEmptyMessage(CODE_RELAX);
                    }
                    break;
                case 2: //发牌
                    L.e(TAG, "GAMEState 发牌   " + new Date(System.currentTimeMillis()).toLocaleString());
                    msg = mHandler.obtainMessage();

                    msg.what = CODE_FAPAI;
                    mHandler.sendMessage(msg);
                    break;
                case 3: //开始下注
                    L.e(TAG, "GAMEState 开始下注   " + new Date(System.currentTimeMillis()).toLocaleString());
                    dealCountDown = gameStateRet.getCountDown();
                    if (dealCountDown < 0) {
                        dealCountDown = 20;
                    }
                    mHandler.sendEmptyMessage(CODE_DEAL);
                    canDeal = true;
                    break;
                case 4:
                    L.e(TAG, "GAMEState 结算   " + new Date(System.currentTimeMillis()).toLocaleString());
                    int countDown = gameStateRet.getCountDown();
                    if (countDown <= 0) countDown = 5;
                    msg = mHandler.obtainMessage();
                    msg.what = CODE_CALCULATE;
                    msg.arg1 = countDown;
                    mHandler.sendMessage(msg);
                    break;
                case 5:
                    L.e(TAG, "GAMEState 开牌   " + new Date(System.currentTimeMillis()).toLocaleString());
                    mHandler.sendEmptyMessage(CODE_RELAX);
                    break;
                default:
                    break;
            }
        }
    }

    @Override
    public void onDisConnected(IoSession session) {

    }

    /*下注阶段*/
    private void doActionDeal() {
        canDeal = true;
        if (left == null) return;
        left.showBack();
        center.showBack();
        right.showBack();
        if (tvState != null) {
            tvState.setVisibility(View.GONE);
            mHandler.sendEmptyMessage(CODE_DEAL_COUNTDOWN);
            tvTimer.setVisibility(View.VISIBLE);
        }

    }

    /*结算阶段 */
    private void doCalculateResult(int countdown) {
        canDeal = false;
        left.showBack();
        center.showBack();
        right.showBack();
        dealCountDown = 0;
        tvTimer.setVisibility(View.GONE);
        tvTimer.setText("" + countdown);
        Message msg = mHandler.obtainMessage();
        msg.arg1 = countdown;
        msg.what = CODE_CALCULATE_COUNTDOWN;
        mHandler.sendMessage(msg);
        showState("揭晓结果");
    }

    /*获取下注信息*/
    private void getDealInfo() {
        RainbowMessage.CGCathNowInfo.Builder builder = RainbowMessage.CGCathNowInfo.newBuilder();
        builder.setUserId(Integer.parseInt(user.getUserId()));
        builder.setLiveId(liveID);
        Packet packet = Packet.newPbPacket(HOpCodeEx.CGCathNowInfo, builder.build().toByteArray());
        packet.setFlag(9);
        packet.setStamp(System.currentTimeMillis());
        packet.setRetCode(0);
        MinaHelper.getInstance().sendMessageToServer(packet);
    }

    /*获取游戏状态*/
    public void getGameState() {
        L.e(TAG, "请求游戏状态");
        requestGameStateTime = System.currentTimeMillis();
        RainbowMessage.CGGameState.Builder open = RainbowMessage.CGGameState.newBuilder();
        open.setLiveId(liveID);
        open.setGameId(GAME_ID);
        open.setUserId(Integer.parseInt(UserProxy.getUser().getUserId()));
        Packet packet = Packet.newPbPacket(HOpCodeEx.CGGameState, open.build().toByteArray());
        packet.setFlag(9);

        packet.setStamp(System.currentTimeMillis());
        packet.setRetCode(0);
        MinaHelper.getInstance().sendMessageToServer(packet);
        L.e(TAG, "请求游戏状态 liveID " + liveID + "UserID  " + UserProxy.getUser().getUserId());
    }


    /*开局*/
    private void startNiuniu() {
        RainbowMessage.CGOpen.Builder open = RainbowMessage.CGOpen.newBuilder();
        open.setGameId(1);
        open.setLiveId(liveID);
        open.setUserId(Integer.parseInt(user.getUserId()));
        Packet packet = Packet.newPbPacket(HOpCodeEx.CGOpen, open.build().toByteArray());
        packet.setFlag(9);
        packet.setStamp(System.currentTimeMillis());
        packet.setRetCode(0);
        MinaHelper.getInstance().sendMessageToServer(packet);
    }

    /*下注*/
    private void sendDealMsg(int index) {
        RainbowMessage.CGBet.Builder builder = RainbowMessage.CGBet.newBuilder();
        builder.setGameId(GAME_ID);
        builder.setUserId(Integer.parseInt(user.getUserId()));
        builder.setLiveId(liveID);
        builder.setToken(UserProxy.getUser().getToken());
        builder.setIndex(index);
        builder.setChessboardId(chessboardId);
        builder.setValue(chipsSelected);
        Packet packet = Packet.newPbPacket(HOpCodeEx.CGBet, builder.build().toByteArray());
        packet.setFlag(9);
        packet.setStamp(System.currentTimeMillis());
        packet.setRetCode(0);
        L.e(TAG, "time send before " + System.currentTimeMillis());
        MinaHelper.getInstance().sendMessageToServer(packet);
        L.e(TAG, "time  send after " + System.currentTimeMillis());
    }

    /*请求牌面结果*/
    private void sendResultReq() {
        RainbowMessage.CGResult.Builder builder = RainbowMessage.CGResult.newBuilder();
        builder.setChessboardId(chessboardId);
        builder.setUserId(Integer.parseInt(user.getUserId()));
        Packet packet = Packet.newPbPacket(HOpCodeEx.CGResult, builder.build().toByteArray());
        packet.setFlag(9);
        packet.setStamp(System.currentTimeMillis());
        packet.setRetCode(0);
        MinaHelper.getInstance().sendMessageToServer(packet);
    }

    private void initGame() {
        if (left == null) return;
        gameTimes = gameInfo.getRateFirst();
        left.setTimes(gameInfo.getRateFirst());
        center.setTimes(gameInfo.getRateSecond());
        right.setTimes(gameInfo.getRateThird());
        checkChipsSelect(llchips10000, 10000);
        checkChipsSelect(llchips1000, 1000);
        checkChipsSelect(llchips100, 100);
    }

}
